<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="format-detection" content="telephone=no"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="icon" href="/images/icons/favicon-16x16.png?v=2.6.2" type="image/png" sizes="16x16"><link rel="icon" href="/images/icons/favicon-32x32.png?v=2.6.2" type="image/png" sizes="32x32"><meta name="description" content="将 Vue 项目中通用组件打包上传 npm 流程">
<meta property="og:type" content="article">
<meta property="og:title" content="Vue 组件上传 npm 流程">
<meta property="og:url" content="https://s4amq.gitee.io/2021/12/15/Vue-%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0-npm-%E6%B5%81%E7%A8%8B/index.html">
<meta property="og:site_name" content="MQ&#39;s Blog">
<meta property="og:description" content="将 Vue 项目中通用组件打包上传 npm 流程">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-12-15T04:24:57.000Z">
<meta property="article:modified_time" content="2021-12-21T07:58:42.967Z">
<meta property="article:author" content="mqchen">
<meta property="article:tag" content="Vue">
<meta property="article:tag" content="npm">
<meta name="twitter:card" content="summary"><title>Vue 组件上传 npm 流程 | MQ's Blog</title><link ref="canonical" href="https://s4amq.gitee.io/2021/12/15/Vue-%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0-npm-%E6%B5%81%E7%A8%8B/"><link rel="dns-prefetch" href="https://cdn.jsdelivr.net"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.12.1/css/all.min.css" type="text/css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" type="text/css"><link rel="stylesheet" href="/css/index.css?v=2.6.2"><script>var Stun = window.Stun || {};
var CONFIG = {
  root: '/',
  algolia: undefined,
  assistSearch: undefined,
  fontIcon: {"prompt":{"success":"fas fa-check-circle","info":"fas fa-arrow-circle-right","warning":"fas fa-exclamation-circle","error":"fas fa-times-circle"},"copyBtn":"fas fa-copy"},
  sidebar: {"offsetTop":"20px","tocMaxDepth":6},
  header: {"enable":true,"showOnPost":true,"scrollDownIcon":true},
  postWidget: {"endText":true},
  nightMode: {"enable":true},
  back2top: {"enable":true},
  codeblock: {"style":"carbon","highlight":"light","wordWrap":false},
  reward: false,
  fancybox: true,
  zoomImage: {"gapAside":"20px"},
  galleryWaterfall: {"colWidth":"100%","gapX":"10px"},
  lazyload: false,
  pjax: undefined,
  externalLink: {"icon":{"enable":true,"name":"fas fa-external-link-alt"}},
  shortcuts: undefined,
  prompt: {"copyButton":"复制","copySuccess":"复制成功","copyError":"复制失败"},
  sourcePath: {"js":"js","css":"css","images":"images"},
};

window.CONFIG = CONFIG;</script><meta name="generator" content="Hexo 5.4.0"></head><body><div class="container" id="container"><header class="header" id="header"><div class="header-inner"><nav class="header-nav header-nav--fixed"><div class="header-nav-inner"><div class="header-nav-menubtn"><i class="fas fa-bars"></i></div><div class="header-nav-menu"><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/"><span class="header-nav-menu-item__icon"><i class="fas fa-home"></i></span><span class="header-nav-menu-item__text">首页</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/archives/"><span class="header-nav-menu-item__icon"><i class="fas fa-folder-open"></i></span><span class="header-nav-menu-item__text">归档</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/categories/"><span class="header-nav-menu-item__icon"><i class="fas fa-layer-group"></i></span><span class="header-nav-menu-item__text">分类</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/tags/"><span class="header-nav-menu-item__icon"><i class="fas fa-tags"></i></span><span class="header-nav-menu-item__text">标签</span></a></div></div><div class="header-nav-mode"><div class="mode"><div class="mode-track"><span class="mode-track-moon"></span><span class="mode-track-sun"></span></div><div class="mode-thumb"></div></div></div></div></nav><div class="header-banner"><div class="header-banner-info"><div class="header-banner-info__title">MQ's Blog</div><div class="header-banner-info__subtitle"></div></div><div class="header-banner-arrow"><div class="header-banner-arrow__icon"><i class="fas fa-angle-down"></i></div></div></div></div></header><main class="main" id="main"><div class="main-inner"><div class="content-wrap" id="content-wrap"><div class="content" id="content"><!-- Just used to judge whether it is an article page--><div id="is-post"></div><div class="post"><header class="post-header"><h1 class="post-title">Vue 组件上传 npm 流程</h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2021-12-15</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2021-12-21</span></span></div></header><div class="post-body"><p>在做 Vue 项目过程中，封装了一个通用组件，想将其上传至 npm 方便后续直接使用。（该组件存在于项目中 src/components/module 目录下，名称为 CitySelect ）</p>

        <h4 id="上传流程"   >
          <a href="#上传流程" class="heading-link"><i class="fas fa-link"></i></a><a href="#上传流程" class="headerlink" title="上传流程"></a>上传流程</h4>
      
        <h5 id="第一步"   >
          <a href="#第一步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第一步" class="headerlink" title="第一步"></a>第一步</h5>
      <p>src 中新建文件夹，命名为组件名，其中新建文件 index.js 用于 vue 插件模式。</p>
<blockquote>
<p>vue 插件模式<br>vue 的插件模式中必须提供一个公开方法 install 。该方法会在使用 Vue.use(Plugin) 时被调用。</p>
</blockquote>
<ul>
<li>index.js</li>
</ul>
<figure class="highlight js"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> CitySelect <span class="keyword">from</span> <span class="string">&#x27;../components/module/CitySelect.vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Vue 插件模式需暴露 install 方法</span></span><br><span class="line"></span><br><span class="line">CitySelect.install = <span class="function"><span class="keyword">function</span> (<span class="params">Vue</span>) </span>&#123;</span><br><span class="line">  Vue.component(CitySelect.name, CitySelect)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> CitySelect</span><br></pre></td></tr></table></div></figure>


        <h5 id="第二步"   >
          <a href="#第二步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第二步" class="headerlink" title="第二步"></a>第二步</h5>
      <p>在根目录 package.json 中配置打包信息</p>
<figure class="highlight json"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;script&quot;</span>: &#123;</span><br><span class="line">	...</span><br><span class="line">	<span class="attr">&quot;city-select&quot;</span>: <span class="string">&quot;vue-cli-service build --target lib ./src/city-select/index.js --dest city-select --name city-select&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>

<p>target lib - 关键字 指定打包的目录<br>name - 打包后的文件名称<br>dest - 打包后的文件夹名称</p>

        <h5 id="第三步"   >
          <a href="#第三步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第三步" class="headerlink" title="第三步"></a>第三步</h5>
      <p>项目根目录上打开终端，执行 <code>npm run city-select</code> 开始打包<br>根目录生成组件文件夹</p>

        <h5 id="第四步"   >
          <a href="#第四步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第四步" class="headerlink" title="第四步"></a>第四步</h5>
      <p>在项目根目录新建文件夹 packages 并将文件 city-select.umd.min.js 复制到该文件夹<br>将 city-select.css 文件复制到 packages 文件夹下 style 子文件夹内</p>

        <h5 id="第五步"   >
          <a href="#第五步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第五步" class="headerlink" title="第五步"></a>第五步</h5>
      <p>在 packages 文件夹中打开终端，执行命令 <code>npm init -y</code> 初始化 package.json 文件</p>

        <h5 id="第六步"   >
          <a href="#第六步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第六步" class="headerlink" title="第六步"></a>第六步</h5>
      <p>修改 package.json 中对应内容</p>
<figure class="highlight json"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;name&quot;</span>: <span class="string">&quot;m-city-select&quot;</span>, 组件名</span><br><span class="line">  <span class="attr">&quot;version&quot;</span>: <span class="string">&quot;1.0.0&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;description&quot;</span>: <span class="string">&quot;&quot;</span>,</span><br><span class="line">  <span class="attr">&quot;main&quot;</span>: <span class="string">&quot;index.js&quot;</span>, 对应打包后的组件js文件名(此处统一修改为了 index.js)</span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">    <span class="attr">&quot;test&quot;</span>: <span class="string">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">&quot;keywords&quot;</span>: [<span class="string">&quot;vue&quot;</span>, <span class="string">&quot;js&quot;</span>, <span class="string">&quot;css&quot;</span>, <span class="string">&quot;form&quot;</span>], 关键字</span><br><span class="line">  <span class="attr">&quot;author&quot;</span>: <span class="string">&quot;xxx&quot;</span>, 作者</span><br><span class="line">  <span class="attr">&quot;license&quot;</span>: <span class="string">&quot;ISC&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>


        <h5 id="第七步"   >
          <a href="#第七步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第七步" class="headerlink" title="第七步"></a>第七步</h5>
      <p>切换为 npm 官方源 <code>nrm use npm</code> (<code>nrm ls</code> 查看当前源)<br>执行 <code>npm login</code> 登录账户</p>

        <h5 id="第八步"   >
          <a href="#第八步" class="heading-link"><i class="fas fa-link"></i></a><a href="#第八步" class="headerlink" title="第八步"></a>第八步</h5>
      <p>执行 <code>npm publish</code> 发布包到 npm</p>
<p>发布完成</p>

        <h4 id="使用流程"   >
          <a href="#使用流程" class="heading-link"><i class="fas fa-link"></i></a><a href="#使用流程" class="headerlink" title="使用流程"></a>使用流程</h4>
      <p>执行 <code>npm i m-city-select</code><br>在需要引入组件的位置进行引入</p>
<figure class="highlight js"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> CitySelect <span class="keyword">from</span> <span class="string">&#x27;m-city-select&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;m-city-select/style/city-select.css&#x27;</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;xxx&#x27;</span>,</span><br><span class="line">  <span class="attr">components</span>: &#123;</span><br><span class="line">    CitySelect,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>

<figure class="highlight html"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">city-select</span>&gt;</span><span class="tag">&lt;/<span class="name">city-select</span>&gt;</span></span><br></pre></td></tr></table></div></figure>


        <h4 id="更新方法"   >
          <a href="#更新方法" class="heading-link"><i class="fas fa-link"></i></a><a href="#更新方法" class="headerlink" title="更新方法"></a>更新方法</h4>
      <p>修改版本号、说明，执行 <code>npm publish</code></p>
</div><footer class="post-footer"><div class="post-ending ending"><div class="ending__text">------ 本文结束，感谢您的阅读 ------</div></div><div class="post-copyright copyright"><div class="copyright-author"><span class="copyright-author__name">本文作者: </span><span class="copyright-author__value"><a href="https://s4amq.gitee.io">mqchen</a></span></div><div class="copyright-link"><span class="copyright-link__name">本文链接: </span><span class="copyright-link__value"><a href="https://s4amq.gitee.io/2021/12/15/Vue-%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0-npm-%E6%B5%81%E7%A8%8B/">https://s4amq.gitee.io/2021/12/15/Vue-%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0-npm-%E6%B5%81%E7%A8%8B/</a></span></div><div class="copyright-notice"><span class="copyright-notice__name">版权声明: </span><span class="copyright-notice__value">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en" rel="external nofollow" target="_blank">BY-NC-SA</a> 许可协议。转载请注明出处！</span></div></div><div class="post-tags"><span class="post-tags-item"><span class="post-tags-item__icon"><i class="fas fa-tag"></i></span><a class="post-tags-item__link" href="https://s4amq.gitee.io/tags/Vue/">Vue</a></span><span class="post-tags-item"><span class="post-tags-item__icon"><i class="fas fa-tag"></i></span><a class="post-tags-item__link" href="https://s4amq.gitee.io/tags/npm/">npm</a></span></div><nav class="post-paginator paginator"><div class="paginator-prev"><a class="paginator-prev__link" href="/2021/12/16/JavaScript-%E7%BB%A7%E6%89%BF%E6%96%B9%E5%BC%8F/"><span class="paginator-prev__icon"><i class="fas fa-angle-left"></i></span><span class="paginator-prev__text">JavaScript 继承方式</span></a></div><div class="paginator-next"><a class="paginator-next__link" href="/2021/12/08/MVVM-%E7%90%86%E8%A7%A3/"><span class="paginator-prev__text">MVVM 理解</span><span class="paginator-next__icon"><i class="fas fa-angle-right"></i></span></a></div></nav></footer></div></div></div><div class="sidebar-wrap" id="sidebar-wrap"><aside class="sidebar" id="sidebar"><div class="sidebar-nav"><span class="sidebar-nav-toc current">文章目录</span><span class="sidebar-nav-ov">站点概览</span></div><section class="sidebar-toc"><ol class="toc"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%8A%E4%BC%A0%E6%B5%81%E7%A8%8B"><span class="toc-number">1.</span> <span class="toc-text">
          上传流程</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E4%B8%80%E6%AD%A5"><span class="toc-number">1.1.</span> <span class="toc-text">
          第一步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E4%BA%8C%E6%AD%A5"><span class="toc-number">1.2.</span> <span class="toc-text">
          第二步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E4%B8%89%E6%AD%A5"><span class="toc-number">1.3.</span> <span class="toc-text">
          第三步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E5%9B%9B%E6%AD%A5"><span class="toc-number">1.4.</span> <span class="toc-text">
          第四步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E4%BA%94%E6%AD%A5"><span class="toc-number">1.5.</span> <span class="toc-text">
          第五步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E5%85%AD%E6%AD%A5"><span class="toc-number">1.6.</span> <span class="toc-text">
          第六步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E4%B8%83%E6%AD%A5"><span class="toc-number">1.7.</span> <span class="toc-text">
          第七步</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AC%AC%E5%85%AB%E6%AD%A5"><span class="toc-number">1.8.</span> <span class="toc-text">
          第八步</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%B5%81%E7%A8%8B"><span class="toc-number">2.</span> <span class="toc-text">
          使用流程</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%9B%B4%E6%96%B0%E6%96%B9%E6%B3%95"><span class="toc-number">3.</span> <span class="toc-text">
          更新方法</span></a></li></ol></section><!-- ov = overview--><section class="sidebar-ov hide"><div class="sidebar-ov-author"><div class="sidebar-ov-author__avatar"><img class="sidebar-ov-author__avatar_img" src="/images/icons/02.gif" alt="avatar"></div><p class="sidebar-ov-author__text">mqchen</p></div><div class="sidebar-ov-social"><a class="sidebar-ov-social-item" href="https://blog.csdn.net/PorkCanteen" target="_blank" rel="noopener" data-popover="CSDN" data-popover-pos="up"><span class="sidebar-ov-social-item__icon">C</span></a><a class="sidebar-ov-social-item" href="https://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&amp;email=2385190394@qq.com/" target="_blank" rel="noopener" data-popover="social.发送邮件" data-popover-pos="up"><span class="sidebar-ov-social-item__icon"><i class="far fa-envelope"></i></span></a></div><div class="sidebar-ov-state"><a class="sidebar-ov-state-item sidebar-ov-state-item--posts" href="/archives/"><div class="sidebar-ov-state-item__count">14</div><div class="sidebar-ov-state-item__name">归档</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--categories" href="/categories/"><div class="sidebar-ov-state-item__count">7</div><div class="sidebar-ov-state-item__name">分类</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--tags" href="/tags/"><div class="sidebar-ov-state-item__count">6</div><div class="sidebar-ov-state-item__name">标签</div></a></div><div class="sidebar-ov-cc"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en" target="_blank" rel="noopener" data-popover="知识共享许可协议" data-popover-pos="up"><img src="/images/cc-by-nc-sa.svg"></a></div></section><div class="sidebar-reading"><div class="sidebar-reading-info"><span class="sidebar-reading-info__text">你已阅读了 </span><span class="sidebar-reading-info__num">0</span><span class="sidebar-reading-info__perc">%</span></div><div class="sidebar-reading-line"></div></div></aside></div><div class="clearfix"></div></div></main><footer class="footer" id="footer"><div class="footer-inner"><div><span>Copyright © 2022</span><span class="footer__icon"><i class="fas fa-pizza-slice"></i></span><span>mqchen</span></div></div></footer><div class="loading-bar" id="loading-bar"><div class="loading-bar__progress"></div></div><div class="back2top" id="back2top"><span class="back2top__icon"><i class="fas fa-rocket"></i></span></div></div><script src="https://cdn.jsdelivr.net/npm/jquery@v3.4.1/dist/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.ui.min.js"></script><script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script><script src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js"></script><script src="/js/utils.js?v=2.6.2"></script><script src="/js/stun-boot.js?v=2.6.2"></script><script src="/js/scroll.js?v=2.6.2"></script><script src="/js/header.js?v=2.6.2"></script><script src="/js/sidebar.js?v=2.6.2"></script></body></html>